package org.hive.testserver.domain.model.schedule;

import java.util.ArrayList;
import java.util.List;

import org.hive.testserver.domain.model.Slave;
import org.hive.testserver.domain.model.Test;
import org.hive.testserver.domain.model.TestRun;
import org.hive.testserver.domain.model.TestState;
import org.hive.testserver.domain.model.WorkSheet;

/**
 * Single pass through tests, allocating a test once to a slave in a first-come first-served basis.
 */
public class SinglePassPolicy implements TestPolicy {

	public SinglePassPolicy() {
		super();
	}
	
	public ScheduledTest nextTestOrNull(TestRun testRun, Slave slave, WorkSheet workSheet) {
		List<Test> tests = remainingTests(testRun, workSheet);
		if (!tests.isEmpty()) {
			return new ScheduledTest(tests.get(0), ScheduleReason.UNTESTED);
		} else {
			return new ScheduledTest(ScheduleReason.NOTHING_SUITABLE_TO_RUN);
		}
	}

	//FIXME terribly expensive - just temporary
	List<Test> remainingTests(TestRun testRun, WorkSheet workSheet) {
		List<Test> remaining = new ArrayList<Test>();
		for (Test test : testRun.getTests()) {
			if (untested(test) || rescheduled(test, workSheet)) {
				remaining.add(test);
			}
		}
		return remaining;
	}

	private boolean rescheduled(Test test, WorkSheet workSheet) {
		return workSheet.isTestRescheduled(test);
	}

	private boolean untested(Test test) {
		return test.currentState().equals(TestState.UNTESTED);
	}


	public void onRunStarted(TestRun testRun) {
		// ignore
	}

	public void onTestStateUpdated(Test test) {
		if (test.currentState() == TestState.PASSED || test.currentState() == TestState.FAILED || test.currentState() == TestState.ABORTED) {
			test.beFinished();
		}
	}
}
